
package io.gps.datatransfer.utils;

import io.gps.datatransfer.CenterChannel;
import io.gps.datatransfer.command.DevServer;
import io.gps.datatransfer.command.TimeObj;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;

import java.util.*;
import java.util.concurrent.*;



/**
 * 系统初始化定义模块
 * @author bcs
 * @version 2.0, $Date: 2020-11-18 11:08:44$
 */
public class SysDef {

	private static Logger logger = Logger.getLogger(SysDef.class);

	/**
	 * 主任务线程池
	 */
	public static ThreadPoolExecutor executor = null;

	/**
	 * 键:sim卡号,值:车辆信息
	 */
	public static ConcurrentHashMap<Object, CenterChannel> sim_server_center = new ConcurrentHashMap<Object, CenterChannel>();

	public static ConcurrentLinkedQueue<Object> allMsgQuery=new ConcurrentLinkedQueue<Object>();

	/**
	 * 键:sim卡号,值:下行回话
	 */
	public static ConcurrentHashMap<String, IoSession> sim_session = new ConcurrentHashMap<String, IoSession>();

	public static Map<String,String> BLACK_LIST = new HashMap<String,String>();

	public static Map<String,Map<String,String>> CAR_LIST = new HashMap<String,Map<String,String>>();

	public static List<TimeObj> time_List = new ArrayList<TimeObj>();

	public static boolean IS_LOG = false;

	public static List<DevServer> UP_SERVER=null;

	/**
	 *  级服务器地址#本地默认使用TCP端口*/
	public static int LOCAL_DEV_PORT=9955;

	/**
	 *  级服务器地址#是否启用时间段限制，true 启用 false 不启用*/
	public static boolean IS_SET_HOUR=true;

	/**
	 *  是否到达运行是时间*/
	public static boolean IS_TIME=false;
	/**
	 *  级服务器地址# 当 IS_SET_HOUR=true  APP_START_END 生效
    # 格式 早8 点 晚上8 点  8:20   晚20 点早 8点   20:8*/
	 public static String APP_START_END="20:8";


	 /** 是否设置所有设备与上级汇报使用一个回话。true 一个 false 一个设备模拟一个回话*/
	public static boolean IS_SET_ONE=true;

	public final static String IS_SET_ONE_SIMKEY="IS_SET_ONE_SIMKEY";

	/**
	 *  是否设置黑名单过滤 黑名单车辆不转发   */
	public static boolean USE_BLACK_LIST=true;

	/**
	 *#最大缓冲区大小	最好在2048左右*/
	public static int MaxReadBufferSize=2048;
	/**
	 *		#session 保持时间*/
	public static int SESSION_HAND_TIMEOUT=30;
	/**
	 *		#链接等待时间--默认:10000 十秒*/
	public static int CONNECT_TIME_OUT=10000;

	/**
	 * 线程池初始大小
	 */
	public static int CORE_THREAD_POOL_SIZE = 5;
	/**
	 * 线程池最大线程数
	 */
	public static int MAX_THREAD_POOL_SIZE = 5;
	/**
	 * 线程存活时间
	 */
	public static long THREAD_KEEP_ALIVE_SECOND = 1;



	/**
	 * 系统数据初始化
	 */
	public static void init() {
 		Map<String, String> prop = null;
		try {
			prop = readProp(FileUtils.getConfigDirect()+"/gps.properties");

			logger.error("--------初始化系统设置-----------" );
			String UP_SERVER_ADDRESS_STR=String.valueOf(prop.get("UP_SERVER_ADDRESS"));

			logger.error("设置上级服务器地址：--" + UP_SERVER_ADDRESS_STR);
			UP_SERVER=Utils.getDevServer(UP_SERVER_ADDRESS_STR);


			LOCAL_DEV_PORT=Integer.parseInt(String.valueOf(prop.get("LOCAL_DEV_PORT")));
			logger.error("设置本地监听端口：--" + LOCAL_DEV_PORT);

			IS_SET_HOUR=Boolean.parseBoolean(String.valueOf(prop.get("IS_SET_HOUR")));
			logger.error("设置是否启用时间段限制：--" + IS_SET_HOUR);

			APP_START_END=Utils.delSpaceNotStrNull(String.valueOf(prop.get("APP_START_END")));
			logger.error("设置时间段限制：--" + APP_START_END);

			IS_SET_ONE=Boolean.parseBoolean(String.valueOf(prop.get("IS_SET_ONE")));
			logger.error("设置是否单一链路：--" + IS_SET_ONE);

			USE_BLACK_LIST=Boolean.parseBoolean(String.valueOf(prop.get("USE_BLACK_LIST")));
			logger.error("设置是否启用黑名单：--" + USE_BLACK_LIST);

			MaxReadBufferSize = Integer.parseInt(String.valueOf(prop.get("MaxReadBufferSize")));
			logger.error("设置信息最大缓冲区大小：--" + MaxReadBufferSize);

			SESSION_HAND_TIMEOUT = Integer.parseInt(String.valueOf(prop
					.get("SESSION_HAND_TIMEOUT")));
			logger.error("设置Session保留时间：--" + SESSION_HAND_TIMEOUT);

			CONNECT_TIME_OUT = Integer.parseInt(String.valueOf(prop
					.get("CONNECT_TIME_OUT")));
			logger.error("设置连接等待间隔（秒）：--" + CONNECT_TIME_OUT);

			CORE_THREAD_POOL_SIZE = Integer.parseInt(String.valueOf(prop
					.get("CORE_THREAD_POOL_SIZE")));
			logger.error("CORE_THREAD_POOL_SIZE--" + CORE_THREAD_POOL_SIZE);

			MAX_THREAD_POOL_SIZE = Integer.parseInt(String.valueOf(prop
					.get("MAX_THREAD_POOL_SIZE")));
			logger.error("MAX_THREAD_POOL_SIZE：--" + MAX_THREAD_POOL_SIZE);

			THREAD_KEEP_ALIVE_SECOND = Long.parseLong(String.valueOf(prop
					.get("THREAD_KEEP_ALIVE_SECOND")));
			logger.error("THREAD_KEEP_ALIVE_SECOND：--" + THREAD_KEEP_ALIVE_SECOND);

			logger.error("--------初始化线程池-----------" );
			executor=new ThreadPoolExecutor(CORE_THREAD_POOL_SIZE,MAX_THREAD_POOL_SIZE, THREAD_KEEP_ALIVE_SECOND,TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
			if(USE_BLACK_LIST){
				FileUtils.InitBlackList();
			}
			if(IS_SET_HOUR){
				String[] times=APP_START_END.split(";");
				if(times!=null &&times.length>=1){
					for (int i = 0; i <times.length ; i++) {
						String[] tempTime=times[i].split("-");
						if(tempTime!=null &&tempTime.length==2){
							TimeObj timeObj=new TimeObj(
									Integer.parseInt(tempTime[0].split(":")[0]),
									Integer.parseInt(tempTime[0].split(":")[1]),
									Integer.parseInt(tempTime[1].split(":")[0]),
									Integer.parseInt(tempTime[1].split(":")[1]));
							time_List.add(timeObj);
						}

					}
				}

				if(time_List.size()<1){
					TimeObj timeObj=new TimeObj(22,0,5,0);
					time_List.add(timeObj);
				}
			}


			IS_LOG = Integer.parseInt(String.valueOf(prop.get("IS_LOG")))==1;
			logger.error("是否输出日志：--" + IS_LOG);
 			logger.error("--------全部初始化完毕-----------" );
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			System.exit(-1);
		} finally {
			if(prop!=null){
				prop.clear();
				prop = null;
			}
		}
	}

	public static Map<String, String> readProp(String f){
		Properties props = PropertiesUtils.PROPERTIES.getFileProperties(f);
		Map<String, String> map=new HashMap<String, String>();
		try {
			Enumeration en=props.propertyNames();
			while (en.hasMoreElements()) {
				String key=(String) en.nextElement();
				String property=props.getProperty(key);
				map.put(key, property);
			}
		} catch (Exception e) {
			e.printStackTrace();
			// TODO: handle exception
		}
		return map;
	}

	public static void setSession(String sim,IoSession session){
		IoSession tempSession=SysDef.sim_session.get(sim);
		if(tempSession==null){
			SysDef.sim_session.put(sim,session);
		}else{
			if(!tempSession.equals(session)){
				tempSession.closeNow();
				SysDef.sim_session.put(sim,session);
			}
		}
	}

	public static void sedMsg(String sim,int msgid,IoBuffer data){
		if(SysDef.IS_SET_ONE){
			sim=SysDef.IS_SET_ONE_SIMKEY;
		}
		for (int i = 0; i < UP_SERVER.size(); i++) {
			CenterChannel center = SysDef.sim_server_center.get(getserverkey(sim,UP_SERVER.get(i).getServerid()));
			if(center!=null&&center.getDevServer().getServerid()!=null){
				center.addMsg(data);
			}
		}

	}

	public static String getserverkey(String sim,String serverid){
		if(SysDef.IS_SET_ONE){
			sim=SysDef.IS_SET_ONE_SIMKEY;
		}
		 return sim+"_"+serverid;
	}

}